package cn.wolfcode.car.business.service.impl;

import cn.wolfcode.car.business.domain.BpmnInfo;
import cn.wolfcode.car.business.domain.CarPackageAudit;
import cn.wolfcode.car.business.domain.ServiceItem;
import cn.wolfcode.car.business.mapper.ServiceItemMapper;
import cn.wolfcode.car.business.query.ServiceItemQuery;
import cn.wolfcode.car.business.service.IBpmnInfoService;
import cn.wolfcode.car.business.service.ICarPackageAuditService;
import cn.wolfcode.car.business.service.IServiceItemService;
import cn.wolfcode.car.common.base.page.TablePageInfo;
import cn.wolfcode.car.common.exception.BusinessException;
import cn.wolfcode.car.common.util.Convert;
import cn.wolfcode.car.shiro.ShiroUtils;
import com.github.pagehelper.PageHelper;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.swing.text.AbstractDocument;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class ServiceItemServiceImpl implements IServiceItemService {

    @Autowired
    private ServiceItemMapper serviceItemMapper;

    @Autowired
    private ICarPackageAuditService carPackageAuditService;



    @Autowired
    private RuntimeService runtimeService;
    
    @Autowired
    private IBpmnInfoService bpmnInfoService;


    @Override
    public TablePageInfo<ServiceItem> query(ServiceItemQuery qo) {
        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        return new TablePageInfo<ServiceItem>(serviceItemMapper.selectForList(qo));
    }


    @Override
    public void save(ServiceItem serviceItem) {
        //细节:页面收集的数据可能不全,此时需要额外填充
        serviceItem.setCreateTime(new Date());

        //重要的属性建议明确的设置

        serviceItem.setSaleStatus(ServiceItem.SALESTATUS_OFF);
        // 必须是套餐才审核
        if(serviceItem.getCarPackage()){
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        }else{
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_NO_REQUIRED);
        }

        serviceItemMapper.insert(serviceItem);
    }

    @Override
    public ServiceItem get(Long id) {
        return serviceItemMapper.selectByPrimaryKey(id);
    }


    @Override
    public void update(ServiceItem serviceItem) {
        //当页面发起更新请求时, 带上数据可能补全,此时如果调用全字段更新语句:updateByPrimaryKey
        //可能存在参数丢失问题. 原因:页面传数据不全, 对象中的属性值会是null, sql执行时可能将null覆盖数据库中数据
        //解决方案:
        //1:重新定义一个update sql, 去明确指定要更新字段
        //2:在原有updatesql 上, 将不需要更新的字段去掉
        //3:使用mybatis 动态set sql
        //4:执行先查询, 再替换,最后更新
        //查询
        //ServiceItem temp = serviceItemMapper.selectByPrimaryKey(serviceItem.getId());
        //替换
        //temp.setName(serviceItem.getName());
        //更新
        // serviceItemMapper.updateByPrimaryKey(serviceItem);

        //业务中要求： 1:在审核中数据不允许修改  2：上架的数据不允许修改
        ServiceItem oldObj = serviceItemMapper.selectByPrimaryKey(serviceItem.getId());
        if(oldObj == null){
            throw new BusinessException("参数异常");
        }

        if(ServiceItem.AUDITSTATUS_AUDITING.equals(oldObj.getAuditStatus())){
            throw new BusinessException("服务项目正在审核中,不可修改");
        }
        if(ServiceItem.SALESTATUS_ON.equals(oldObj.getSaleStatus())){
            throw new BusinessException("上架服务项目不能修改，请下架后再修改");
        }
        //选择第二个
        serviceItemMapper.updateByPrimaryKey(serviceItem);

    }

    @Override
    public void deleteBatch(String ids) {
        Long[] dictIds = Convert.toLongArray(ids);
        for (Long dictId : dictIds) {
            serviceItemMapper.deleteByPrimaryKey(dictId);
        }
    }

    @Override
    public List<ServiceItem> list() {
        return serviceItemMapper.selectAll();
    }

    @Override
    public void saleOn(Long id) {
        ServiceItem serviceItem = serviceItemMapper.selectByPrimaryKey(id);
        if(serviceItem == null || !ServiceItem.SALESTATUS_OFF.equals(serviceItem.getSaleStatus())){
            throw new  BusinessException("参数异常");
        }
        //满足上传条件
        if(!serviceItem.getCarPackage()){
            //1:如果普通服务单项, 直接上架
            serviceItemMapper.changeSaleStatus(id, ServiceItem.SALESTATUS_ON);
            return;
        }else{
            //2:如果是套餐, 判断当前是否审核通过,才允许上架
            if(ServiceItem.AUDITSTATUS_APPROVED.equals(serviceItem.getAuditStatus())){
                serviceItemMapper.changeSaleStatus(id, ServiceItem.SALESTATUS_ON);
                return;
            }else{
                throw new  BusinessException("服务套餐必须审核通过之后才能上架");
            }
        }
        //上架成功之后要做啥逻辑:修改上架状态
    }

    @Override
    public void saleOff(Long id) {
        ServiceItem serviceItem = serviceItemMapper.selectByPrimaryKey(id);
        if(serviceItem == null || !ServiceItem.SALESTATUS_ON.equals(serviceItem.getSaleStatus())){
            throw new  BusinessException("参数异常");
        }
        serviceItemMapper.changeSaleStatus(id, ServiceItem.SALESTATUS_OFF);
    }

    @Override
    public void startAudit(Long id, Long bpmnInfoId, Long director, Long finance, String info) {
        ServiceItem serviceItem = serviceItemMapper.selectByPrimaryKey(id);
        //满足审核条件
        if(serviceItem == null || !serviceItem.getCarPackage()
                || !ServiceItem.AUDITSTATUS_INIT.equals(serviceItem.getAuditStatus())){
            throw new BusinessException("参数异常， 不允许进行审核");
        }
        //套餐服务状态变动--审核中
        serviceItemMapper.changeAuditStatus(id, ServiceItem.AUDITSTATUS_AUDITING);
        //保存套餐审核记录对象
        CarPackageAudit carPackageAudit = new CarPackageAudit();
        carPackageAudit.setServiceItemId(id);
        carPackageAudit.setServiceItemInfo(serviceItem.getInfo());
        carPackageAudit.setServiceItemPrice(serviceItem.getDiscountPrice());
        carPackageAudit.setCreateTime(new Date());
        carPackageAudit.setCreator(ShiroUtils.getLoginName());
        carPackageAudit.setAuditorId(director);  //第一审核人
        carPackageAudit.setBpmnInfoId(bpmnInfoId);
        carPackageAudit.setInfo(info);
        carPackageAudit.setStatus(CarPackageAudit.STATUS_IN_ROGRESS);
        carPackageAuditService.save(carPackageAudit);

        //启动服务定价审核流程
        Map<String, Object> map = new HashMap<>();
        //1：指定审核人的人（店长/财务）
        if(director != null){
            map.put("director", director);
        }
        if(finance != null){
            map.put("finance", finance);
        }
        //2: 指定审核价格
        map.put("discountPrice", serviceItem.getDiscountPrice().longValue());
        //3: 绑定businessKey
        String businessKey = carPackageAudit.getId().toString();

        BpmnInfo bpmnInfo = bpmnInfoService.get(bpmnInfoId);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(bpmnInfo.getActProcessKey(), businessKey, map);

        //后续再update
        carPackageAuditService.updateInstanceId(carPackageAudit.getId(), processInstance.getId());
    }

    @Override
    public void changeAuditStatus(Long id, Integer auditStatus) {
        serviceItemMapper.changeAuditStatus(id, auditStatus);
    }
}
